/* eslint-disable no-console */
import express from 'express'
import expressWs from 'express-ws'
import pkg from 'fast-glob'
import { FileWatcher } from './src/common/file_watcher.js'

const { glob } = pkg

// noinspection JSUnusedLocalSymbols
function logger(message, type) {
  const logEntry = {
    type: type || 'INFO',
    message,
    timestamp: new Date().toLocaleTimeString('zh-CN', { hour12: false }),
  }

  console.log(`[${logEntry.timestamp}] [${logEntry.type}] ${logEntry.message}`)
}

function InitWebSocket() {
  const { app } = expressWs(express())

  // 配置参数
  const HEARTBEAT_INTERVAL = 25000
  const clients = new Map()

  app.ws('/plugin', (ws, req) => {
    const clientId = req.headers['sec-websocket-key']
    clients.set(clientId, {
      ws,
      lastPong: Date.now(),
    })

    // 心跳检测
    const heartbeat = setInterval(() => {
      if (Date.now() - clients.get(clientId).lastPong > HEARTBEAT_INTERVAL * 1.5) {
        ws.terminate()
        return
      }
      ws.ping()
    }, HEARTBEAT_INTERVAL)

    ws.on('message', (data) => {
      if (data === 'pong') {
        clients.get(clientId).lastPong = Date.now()
      }
      else {
        const msg = JSON.parse(data)
        if (msg.type === 'REFRESH_RESULT') {
          if (msg.success) {
            logger(`[server] \u001B[1;32m刷新成功\u001B[0m ${msg.title} (${msg.url})`)
          }
          else if (msg.error) {
            logger(`[server] \u001B[1;31m刷新失败\u001B[0m ${msg.title} (${msg.url})`)
          }
          if (msg.last) {
            logger(`[server] \u001B[1;35m全部刷新完成\u001B[0m`)
          }
        }
      }
    })

    ws.on('close', () => {
      clearInterval(heartbeat)
      clients.delete(clientId)
    })

    sendRefreshMessage(ws)
  })

  app.listen(8080, () => console.log('[server] 服务运行在 ws://localhost:8080'))
}

// 检测文件，如：**/*.ts、**/*.js
const matchGlob = 'dist/app.js'
// eslint-disable-next-line antfu/no-top-level-await
const files = await glob(matchGlob, { ignore: ['**/node_modules/**'] })
const watcher = new FileWatcher(
  files,
  { persistent: true },
  msg => console.log(`[watcher] ${msg}`),
)

function sendRefreshMessage(ws) {
  let debounceTimer
  watcher._watcher.on('change', () => {
    clearTimeout(debounceTimer)
    debounceTimer = setTimeout(() => {
      ws.send(JSON.stringify({
        type: 'REFRESH_TAB',
        urls: [
          '*://blog.csdn.net/**/*',
          '*://zhuanlan.zhihu.com/p/*',
          '*://www.jianshu.com/p/*',
          '*://www.baidu.com/*',
        ],
      }))
    }, 500) // 合并短暂时间的文件变化为一次刷新，默认为 500ms
  })
}

watcher.start() // 启动监听
watcher._watcher.on('ready', () => {
  console.log('')
  InitWebSocket()
})
